import datetime
import os
import asyncio
import logging
from modules import botpy
from modules.botpy.message import Message, C2CMessage
from modules.botpy.ext.cog_yaml import read
from modules.botpy import Client
from modules.others.deleteFileInFolder import delete_files_in_folder
from modules.others.base import (
    module_regist,
    CommandHandler,
)
from plugins._register import handle_plugins_commands

root_logger = logging.getLogger()  # bot框架自带rootlogger
root_logger.setLevel(logging.INFO)


class MyClient(Client):
    def __init__(self, intents, config, cmd_handler) -> None:
        super().__init__(intents=intents)
        self.config = config
        self.cmd_handler = cmd_handler
        self.lock = asyncio.Lock()
        self.message = None
        self.userID = None
        self.groupID = None
        self.infos = {}
        self.msg_context = {}  # 存储任务上下文，防串回复

    async def on_ready(self) -> None:
        # 重载模块
        await module_regist(1, self.cmd_handler, self.lock, self.reply)

    async def init_seq(self, message) -> None:
        current_task = asyncio.current_task()
        self.msg_context[current_task] = message  # 记录本协程对应的 message

        self.message = message
        self.admin = False
        self.msg = message.content.strip()
        await self.get_userID()
        self.infos["userID"] = self.userID
        self.infos["groupID"] = self.groupID
        self.infos["admin"] = self.admin  # 传给模块用

    async def format_log(self, time: str) -> None:
        if self.groupID != self.userID:
            content = f"{time} 群聊：{self.msg} ##群号：{self.groupID}"
        else:
            content = f"{time} 单聊：{self.msg} ##用户ID：{self.userID}"
        logging.info(content)

    async def reply(
        self,
        content: str = "",
        image: str = None,  # 文件路径
        # keyboard=None,##腾讯已取消kb权限
        img_url: str = None,
        delete_after_send: bool = False,
        img_b64: bytes = None
    ) -> None:
        current_task = asyncio.current_task()
        message = self.msg_context.get(current_task)
        if message is None:
            logging.warning(
                "Warning: 未找到对应 message 上下文，可能在 init_seq 前调用 reply()"
            )
            return
        payload = {}
        payload["content"] = content

        if img_url:
            payload["img_url"] = img_url
        if image:
            payload["image"] = image
        # if keyboard:
        #     payload["keyboard"] = keyboard
        if img_b64:  # 增加支持base64图片，其实就是image_path省去打开图片
            payload["img_b64"] = img_b64
        if payload:
            try:
                await message.reply(**payload)
            except Exception as e:
                await message.reply(content=f"[ReplyError] 发送消息失败: {e}")

        logging.info("reply done")

        if image and delete_after_send:
            try:
                os.remove(image)
            except FileNotFoundError:
                pass

    async def get_userID(self) -> None:
        try:  # 群
            self.userID = self.message.author.member_openid
            self.groupID = self.message.group_openid
        except:  # 私
            self.userID = self.message.author.user_openid
            self.groupID = self.userID
        if self.userID in self.config["admin"]:
            self.admin = True

    async def on_group_at_message_create(self, message: Message) -> None:
        task = asyncio.current_task()  # ← 获取当前任务对象（很重要）
        try:
            await self.init_seq(message)

            if self._is_blacklisted():
                return

            await self._log_message()

            if await handle_plugins_commands(self):
                return

            await self._handle_command(message)

        finally:
            self.msg_context.pop(task, None)

    async def on_c2c_message_create(self, message: C2CMessage) -> None:
        await self.init_seq(message)
        await self.on_group_at_message_create(message)

    def _is_blacklisted(self) -> bool:
        return self.groupID in self.config.get("bangroup", [])

    async def _log_message(self) -> None:
        time = datetime.datetime.now().strftime("%H:%M:%S")
        await self.format_log(time)

    async def _handle_command(self, message: Message) -> None:
        async with asyncio.Lock():
            try:
                async with asyncio.timeout(30):
                    await self.cmd_handler.handle_message(
                        message, None, self.reply, self.infos
                    )
            except asyncio.TimeoutError:
                logging.warning(f"{message.content} --- 超时")
            except Exception as e:
                logging.exception(f"[Error] 处理消息时发生异常: {e}")


def main() -> None:
    # 创建并配置客户端
    delete_files_in_folder("./data/cache/")

    config = read(os.path.join(os.path.dirname(__file__), "config.yaml"))
    intents = botpy.Intents(public_messages=True, interaction=True)
    Handler = CommandHandler()
    client = MyClient(intents=intents, config=config, cmd_handler=Handler)
    logging.info("O神，启动...")
    client.run(appid=config["appid"], secret=config["secret"])


if __name__ == "__main__":
    main()
